#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
WitTkChart 演示脚本

这个脚本展示了如何使用WitTkChart库创建各种类型的图表。
"""

import tkinter as tk
from tkinter import ttk
import random
from wittkchart import WitTkChart

# 示例数据
SAMPLE_DATA = {
    'bar': {
        'data': [65, 59, 80, 81, 56, 55, 72],
        'categories': ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
        'title': '一周销售额统计'
    },
    'line': {
        'data': [12, 19, 3, 5, 2, 3, 15],
        'categories': ['一月', '二月', '三月', '四月', '五月', '六月', '七月'],
        'title': '月度用户增长趋势'
    },
    'pie': {
        'data': [35, 25, 20, 15, 5],
        'categories': ['A产品', 'B产品', 'C产品', 'D产品', 'E产品'],
        'title': '产品销售占比'
    },
    'scatter': {
        'data': [(random.randint(10, 90), random.randint(10, 90)) for _ in range(50)],
        'categories': [],
        'title': '身高体重分布散点图'
    },
    'radar': {
        'data': [65, 59, 80, 81, 56, 55, 40],
        'categories': ['语文', '数学', '英语', '物理', '化学', '生物', '历史'],
        'title': '学生成绩雷达图'
    },
    'tree': {
        'data': [10, 15, 20, 25],
        'categories': ['研发部', '市场部', '销售部', '人事部'],
        'title': '公司部门架构'
    },
    'sunburst': {
        'data': [30, 25, 20, 15, 10],
        'categories': ['华东', '华北', '华南', '西南', '东北'],
        'title': '区域销售分布'
    },
    'boxplot': {
        'data': [
            [45, 55, 65, 75, 85],  # 班级1: 数学成绩分布
            [50, 60, 70, 80, 90],  # 班级2: 数学成绩分布
            [40, 50, 60, 70, 80],  # 班级3: 数学成绩分布
            [35, 45, 55, 65, 75],  # 班级4: 数学成绩分布
            [55, 65, 75, 85, 95]   # 班级5: 数学成绩分布
        ],
        'categories': ['班级1', '班级2', '班级3', '班级4', '班级5'],
        'title': '各班级数学成绩分布箱形图'
    },
    'heatmap': {
        'data': [
            [1, 2, 3, 4, 5],
            [2, 3, 4, 5, 6],
            [3, 4, 5, 6, 7],
            [4, 5, 6, 7, 8]
        ],
        'categories': ['A', 'B', 'C', 'D', 'E'],
        'title': '热力图示例'
    },
    'map': {
        'data': [10, 20, 30, 40, 50],
        'categories': ['区域1', '区域2', '区域3', '区域4', '区域5'],
        'title': '地图示例'
    },
    'sankey': {
        'data': [10, 20, 30, 40, 50],
        'categories': ['来源1', '来源2', '去向1', '去向2', '去向3'],
        'title': '桑基图示例'
    },
    'funnel': {
        'data': [100, 80, 60, 40, 20, 10],
        'categories': ['访问', '注册', '添加购物车', '下单', '支付', '完成'],
        'title': '销售漏斗图'
    },
    'gauge': {
        'data': [68],
        'categories': ['完成度'],
        'title': '项目进度仪表盘'
    }
}

def create_demo_app():
    """
    创建WitTkChart演示应用
    """
    # 创建主窗口
    root = tk.Tk()
    root.title('WitTkChart 演示')
    root.geometry('1000x700')
    
    # 创建控制区域
    control_frame = ttk.Frame(root, padding=10)
    control_frame.pack(side=tk.TOP, fill=tk.X)
    
    # 创建图表类型选择
    ttk.Label(control_frame, text='选择图表类型:').pack(side=tk.LEFT, padx=5)
    chart_type_var = tk.StringVar(value='bar')
    chart_type_combo = ttk.Combobox(
        control_frame, 
        textvariable=chart_type_var, 
        values=list(SAMPLE_DATA.keys()),
        width=15
    )
    chart_type_combo.pack(side=tk.LEFT, padx=5)
    
    # 创建动态更新复选框
    dynamic_var = tk.BooleanVar(value=False)
    dynamic_check = ttk.Checkbutton(control_frame, text='启用动态更新', variable=dynamic_var)
    dynamic_check.pack(side=tk.LEFT, padx=10)
    
    # 创建更新按钮
    update_button = ttk.Button(control_frame, text='更新图表')
    update_button.pack(side=tk.LEFT, padx=5)
    
    # 创建重置按钮
    reset_button = ttk.Button(control_frame, text='重置数据')
    reset_button.pack(side=tk.LEFT, padx=5)
    
    # 创建图表区域
    chart_frame = ttk.Frame(root, padding=10)
    chart_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
    
    # 创建图表对象
    chart_data = SAMPLE_DATA['bar']
    chart = WitTkChart(
        root=chart_frame, 
        chart_type='bar', 
        data=chart_data['data'], 
        categories=chart_data['categories'],
        title=chart_data['title']
    )
    
    # 定义更新图表函数
    def update_chart():
        """
        更新图表显示
        """
        chart_type = chart_type_var.get()
        chart_data = SAMPLE_DATA[chart_type]
        
        # 设置新的图表类型和数据
        chart.set_chart_type(chart_type)
        chart.set_data(chart_data['data'], chart_data['categories'])
        chart.set_title(chart_data['title'])
        
        # 启用或禁用动态更新
        if dynamic_var.get():
            chart.enable_dynamic_update(1000)
        else:
            chart.disable_dynamic_update()
    
    # 定义重置数据函数
    def reset_data():
        """
        重置图表数据为随机值
        """
        chart_type = chart_type_var.get()
        original_data = SAMPLE_DATA[chart_type]['data']
        original_categories = SAMPLE_DATA[chart_type]['categories']
        
        # 根据不同图表类型生成随机数据
        if chart_type == 'scatter':
            # 散点图：二维数据
            new_data = [(random.randint(10, 90), random.randint(10, 90)) for _ in range(50)]
        elif chart_type == 'boxplot':
            # 箱形图：每组包含[min, q1, median, q3, max]，并确保数据的统计意义
            new_data = []
            for _ in range(len(original_data)):
                # 生成更有统计意义的箱形图数据
                # 基础值范围在30-70之间，模拟考试分数等实际数据
                base = random.randint(30, 70)
                # 确保数据符合箱形图的统计特性
                min_val = base - random.randint(5, 15)
                q1 = min_val + random.randint(8, 15)
                median = q1 + random.randint(5, 10)
                q3 = median + random.randint(5, 10)
                max_val = q3 + random.randint(5, 15)
                
                new_data.append([min_val, q1, median, q3, max_val])
        elif chart_type == 'heatmap':
            # 热力图：二维数组
            new_data = []
            for row in original_data:
                new_row = []
                for _ in row:
                    new_row.append(random.randint(1, 10))
                new_data.append(new_row)
        elif chart_type == 'gauge':
            # 仪表盘：单个数值
            new_data = [random.randint(0, 100)]
        else:
            # 其他图表类型：一维数组
            new_data = [random.randint(10, 100) for _ in original_data]
        
        # 更新图表数据
        chart.set_data(new_data, original_categories)
    
    # 绑定按钮事件
    update_button.config(command=update_chart)
    reset_button.config(command=reset_data)
    chart_type_combo.bind('<<ComboboxSelected>>', lambda event: update_chart())
    
    return root

def create_comparison_demo():
    """
    创建多个图表对比演示
    """
    # 创建主窗口
    root = tk.Tk()
    root.title('WitTkChart 多图表对比')
    root.geometry('1200x800')
    
    # 创建说明标签
    ttk.Label(root, text='多图表类型对比展示', font=('SimHei', 14)).pack(pady=10)
    
    # 创建图表容器
    charts_frame = ttk.Frame(root)
    charts_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
    
    # 创建四个图表进行对比
    # 1. 柱状图
    bar_frame = ttk.LabelFrame(charts_frame, text='柱状图', padding=5)
    bar_frame.grid(row=0, column=0, sticky=tk.NSEW, padx=5, pady=5)
    bar_data = SAMPLE_DATA['bar']
    bar_chart = WitTkChart(
        root=bar_frame, 
        width=500, 
        height=300,
        chart_type='bar', 
        data=bar_data['data'], 
        categories=bar_data['categories'],
        title='销售额对比'
    )
    
    # 2. 折线图
    line_frame = ttk.LabelFrame(charts_frame, text='折线图', padding=5)
    line_frame.grid(row=0, column=1, sticky=tk.NSEW, padx=5, pady=5)
    line_data = SAMPLE_DATA['line']
    line_chart = WitTkChart(
        root=line_frame, 
        width=500, 
        height=300,
        chart_type='line', 
        data=line_data['data'], 
        categories=line_data['categories'],
        title='用户增长趋势'
    )
    
    # 3. 饼图
    pie_frame = ttk.LabelFrame(charts_frame, text='饼图', padding=5)
    pie_frame.grid(row=1, column=0, sticky=tk.NSEW, padx=5, pady=5)
    pie_data = SAMPLE_DATA['pie']
    pie_chart = WitTkChart(
        root=pie_frame, 
        width=500, 
        height=300,
        chart_type='pie', 
        data=pie_data['data'], 
        categories=pie_data['categories'],
        title='销售占比'
    )
    
    # 4. 箱形图
    boxplot_frame = ttk.LabelFrame(charts_frame, text='箱形图', padding=5)
    boxplot_frame.grid(row=1, column=1, sticky=tk.NSEW, padx=5, pady=5)
    boxplot_data = SAMPLE_DATA['boxplot']
    boxplot_chart = WitTkChart(
        root=boxplot_frame, 
        width=500, 
        height=300,
        chart_type='boxplot', 
        data=boxplot_data['data'], 
        categories=boxplot_data['categories'],
        title='各班级数学成绩分布箱形图'
    )
    
    # 设置网格权重，使图表可以自适应大小
    charts_frame.grid_columnconfigure(0, weight=1)
    charts_frame.grid_columnconfigure(1, weight=1)
    charts_frame.grid_rowconfigure(0, weight=1)
    charts_frame.grid_rowconfigure(1, weight=1)
    
    return root

def create_boxplot_comparison_demo():
    """
    创建箱形图比较演示，展示不同场景下的箱形图应用
    """
    # 创建主窗口
    root = tk.Tk()
    root.title('WitTkChart 箱形图比较演示')
    root.geometry('1200x800')
    
    # 创建说明标签
    ttk.Label(root, text='箱形图在不同场景下的应用示例', font=('SimHei', 14)).pack(pady=10)
    
    # 创建图表容器
    charts_frame = ttk.Frame(root)
    charts_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
    
    # 创建四个不同场景的箱形图进行对比
    # 1. 学生成绩比较
    scores_frame = ttk.LabelFrame(charts_frame, text='学生成绩比较', padding=5)
    scores_frame.grid(row=0, column=0, sticky=tk.NSEW, padx=5, pady=5)
    scores_data = {
        'data': [
            [45, 55, 65, 75, 85],  # 班级1: 数学成绩分布
            [50, 60, 70, 80, 90],  # 班级2: 数学成绩分布
            [40, 50, 60, 70, 80],  # 班级3: 数学成绩分布
            [35, 45, 55, 65, 75],  # 班级4: 数学成绩分布
            [55, 65, 75, 85, 95]   # 班级5: 数学成绩分布
        ],
        'categories': ['班级1', '班级2', '班级3', '班级4', '班级5'],
        'title': '各班级数学成绩分布箱形图'
    }
    scores_chart = WitTkChart(
        root=scores_frame, 
        width=550, 
        height=350,
        chart_type='boxplot', 
        data=scores_data['data'], 
        categories=scores_data['categories'],
        title=scores_data['title']
    )
    
    # 2. 产品质量控制
    quality_frame = ttk.LabelFrame(charts_frame, text='产品质量控制', padding=5)
    quality_frame.grid(row=0, column=1, sticky=tk.NSEW, padx=5, pady=5)
    quality_data = {
        'data': [
            [95, 97, 98, 99, 101],  # 生产线A: 产品尺寸偏差
            [94, 96, 97, 98, 100],  # 生产线B: 产品尺寸偏差
            [96, 98, 99, 100, 102],  # 生产线C: 产品尺寸偏差
            [93, 95, 96, 97, 99]    # 生产线D: 产品尺寸偏差
        ],
        'categories': ['生产线A', '生产线B', '生产线C', '生产线D'],
        'title': '各生产线产品尺寸偏差箱形图'
    }
    quality_chart = WitTkChart(
        root=quality_frame, 
        width=550, 
        height=350,
        chart_type='boxplot', 
        data=quality_data['data'], 
        categories=quality_data['categories'],
        title=quality_data['title']
    )
    
    # 3. 销售数据波动
    sales_frame = ttk.LabelFrame(charts_frame, text='销售数据波动', padding=5)
    sales_frame.grid(row=1, column=0, sticky=tk.NSEW, padx=5, pady=5)
    sales_data = {
        'data': [
            [100, 150, 200, 250, 300],  # 一季度: 周销售额分布
            [120, 180, 230, 280, 320],  # 二季度: 周销售额分布
            [150, 200, 250, 300, 350],  # 三季度: 周销售额分布
            [180, 250, 300, 350, 400]   # 四季度: 周销售额分布
        ],
        'categories': ['一季度', '二季度', '三季度', '四季度'],
        'title': '各季度周销售额分布箱形图'
    }
    sales_chart = WitTkChart(
        root=sales_frame, 
        width=550, 
        height=350,
        chart_type='boxplot', 
        data=sales_data['data'], 
        categories=sales_data['categories'],
        title=sales_data['title']
    )
    
    # 4. 员工绩效评估
    performance_frame = ttk.LabelFrame(charts_frame, text='员工绩效评估', padding=5)
    performance_frame.grid(row=1, column=1, sticky=tk.NSEW, padx=5, pady=5)
    performance_data = {
        'data': [
            [60, 70, 75, 80, 90],  # 团队A: 绩效分数分布
            [65, 75, 80, 85, 95],  # 团队B: 绩效分数分布
            [55, 65, 70, 75, 85],  # 团队C: 绩效分数分布
            [70, 80, 85, 90, 100]  # 团队D: 绩效分数分布
        ],
        'categories': ['团队A', '团队B', '团队C', '团队D'],
        'title': '各团队员工绩效分数分布箱形图'
    }
    performance_chart = WitTkChart(
        root=performance_frame, 
        width=550, 
        height=350,
        chart_type='boxplot', 
        data=performance_data['data'], 
        categories=performance_data['categories'],
        title=performance_data['title']
    )
    
    # 设置网格权重，使图表可以自适应大小
    charts_frame.grid_columnconfigure(0, weight=1)
    charts_frame.grid_columnconfigure(1, weight=1)
    charts_frame.grid_rowconfigure(0, weight=1)
    charts_frame.grid_rowconfigure(1, weight=1)
    
    return root

def main():
    """
    主函数
    """
    # 创建一个简单的菜单，让用户选择演示类型
    menu_root = tk.Tk()
    menu_root.title('WitTkChart 演示选择')
    menu_root.geometry('300x250')
    menu_root.resizable(False, False)
    
    # 居中窗口
    menu_root.update_idletasks()
    width = menu_root.winfo_width()
    height = menu_root.winfo_height()
    x = (menu_root.winfo_screenwidth() // 2) - (width // 2)
    y = (menu_root.winfo_screenheight() // 2) - (height // 2)
    menu_root.geometry('{}x{}+{}+{}'.format(width, height, x, y))
    
    # 创建说明标签
    ttk.Label(menu_root, text='请选择演示类型:', font=('SimHei', 12)).pack(pady=20)
    
    # 创建按钮框架
    buttons_frame = ttk.Frame(menu_root)
    buttons_frame.pack(pady=10)
    
    # 定义打开演示的函数
    def open_basic_demo():
        """打开基础演示"""
        menu_root.destroy()
        app = create_demo_app()
        app.mainloop()
    
    def open_comparison_demo():
        """打开对比演示"""
        menu_root.destroy()
        app = create_comparison_demo()
        app.mainloop()
    
    def open_boxplot_comparison_demo():
        """打开箱形图比较演示"""
        menu_root.destroy()
        app = create_boxplot_comparison_demo()
        app.mainloop()
    
    # 创建按钮
    basic_button = ttk.Button(buttons_frame, text='基础图表演示', command=open_basic_demo, width=20)
    basic_button.pack(pady=5)
    
    comparison_button = ttk.Button(buttons_frame, text='多图表对比演示', command=open_comparison_demo, width=20)
    comparison_button.pack(pady=5)
    
    boxplot_comparison_button = ttk.Button(buttons_frame, text='箱形图比较演示', command=open_boxplot_comparison_demo, width=20)
    boxplot_comparison_button.pack(pady=5)
    
    # 启动菜单
    menu_root.mainloop()

if __name__ == '__main__':
    main()